#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>

#define NUM 10

typedef void (*fun_t)();//函数指针

fun_t handlerTask[NUM];

//样例任务
void task1()
{
    printf("handler task1\n");
}

void task2()
{
    printf("handler task2\n");
}

void task3()
{
    printf("handler task3\n");
}
 
void loadTask()
{
    memset(handlerTask,0,sizeof(handlerTask));
    handlerTask[0]=task1; 
    handlerTask[1]=task2;
    handlerTask[2]=task3;
}

int main()
{
    pid_t id=fork();
    assert(id != -1);
    if(id == 0)
    {
      //子进程
      int cnt=10;
      while(cnt)
      {
        printf("child running, pid: %d, ppid: %d , cnt: %d\n",getpid(),getppid(),cnt--);
        sleep(3);
      }
      exit(10);
    }

    loadTask();
    //parent
    int status = 0;
    while(1)
    {
        pid_t ret = waitpid(id,&status,WNOHANG);//WNOHANG: 非阻塞-> 子进程没有退出，父进程检测的时候立即返回
        if( ret == 0 )
        {
            //waitpid调用成功 && 子进程没有退出
            //子进程没有退出，我的waitpid没有等待失败，仅仅是检测到了子进程没有退出
            printf("wait done, but child  is running...... , parent running other things\n");
            int i=0;
            for(i=0;handlerTask[i] != NULL;i++)
            {
                handlerTask[i]();//采用回调的方式，执行我们想让父进程在空闲的时候做的事
            }
        }
        else if(ret > 0)
        {
            // waitpid调用成功 && 子进程退出了
            printf("wait success, exit code: %d , sig: %d\n",((status>>8) & 0xFF),status & 0x7F);
            break;
        }
        else
        {
            //waitpid调用失败
            printf("waitpid call failde\n");
            break;
        }
        sleep(1);
    }

   // //parent
   // int status = 0;
   // // 1.让OS释放子进程的僵尸进程
   // // 2.获取子进程的退出结果
   // // 在等待期间，子进程没有退出的时候，父进程只能阻塞等
   // int ret=waitpid(id,&status,0);
   // if(ret > 0)
   // {
   //     // 是否正常退出
   //     if(WIFEXITED(status))
   //     {
   //         //判断子进程结果是否ok
   //         printf("exit code: %d\n",WEXITSTATUS(status));
   //     }
   //     else
   //     {
   //         printf("child exit not normal!\n");
   //     }
   // //    printf("wait success, exit code: %d, sig: %d\n",((status>>8) & 0xFF),(status &0x7F));
   // }
    return 0;
}
